package conversion;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import servlet.ConnectionHelper;
import dataobjects.AddMessage;
import dataobjects.Category;
import dataobjects.DeleteQuery;
import dataobjects.DislikeQuery;
import dataobjects.HistoryQuery;
import dataobjects.IndifferentQuery;
import dataobjects.LikeQuery;
import dataobjects.Message;
import dataobjects.MessageQuery;
import dataobjects.ReportQuery;

public class Factory {

	public static List<Message> getMessages(MessageQuery obj) {
		Long cat = obj.getCategory();
		List<Message> messages = new ArrayList<Message>();
		if( cat == null) {
			for(Category category : Category.values()){
				messages.addAll(getMessagesOfCategory(obj, category.getID()));
			}
		} else {
			messages.addAll( getMessagesOfCategory(obj, cat));
			
		}
		
		return messages;
	}

	private static List<Message> getMessagesOfCategory(MessageQuery obj,
			Long cat) {
		DBDataSet set = null;
		List<Message> messageList = new ArrayList<Message>();
		String myquery = "select " + " S.id,"
				+ " S.categoryID, S.message, S.nickname, "
				+ " ifnull(V.positiveVotes,0) as likes, "
				+ " ifnull(V.negativeVotes,0) as dislikes, "
				+ " ifnull(V.indifferentVotes,0) as indifferent"
				+ " from suggestions S left join votes V"
				+ " on S.id = V.id where 1=1 ";

		myquery += cat != null ? " and S.categoryID = " + cat.longValue() : "";

		String ids = createIdList(obj.getAlreadyReadMessages());

		myquery += ids != "" ? " and S.id not in ( " + ids + ")" : "";

		myquery += " limit 5";

		try {
			set = ConnectionHelper.selectQuery(myquery);

			for (int i = 0; i < set.length(); i++) {
				long id = ((Number) set.getData(i, "id")).longValue();
				long categoryID = ((Number) set.getData(i, "categoryID"))
						.longValue();
				String messageText = (String) set.getData(i, "message");
				String nickname = (String) set.getData(i, "nickname");
				long likes = ((Number) set.getData(i, "likes")).longValue();
				long dislikes = ((Number) set.getData(i, "dislikes"))
						.longValue();
				long indifferent = ((Number) set.getData(i, "indifferent"))
						.longValue();

				Message message = new Message();
				message.setId(id);
				message.setCategoryID(categoryID);
				message.setMessage(messageText);
				message.setLikes(likes);
				message.setDislikes(dislikes);
				message.setIndifferent(indifferent);
				message.setNickname(nickname);
				messageList.add(message);
			}
		} catch (Exception exe) {
			Message msg = new Message();
			msg.setId(1L);
			msg.setCategoryID(12312312L);
			msg.setMessage("Error: " + exe.getMessage() + set);
			messageList.add(msg);
		}

		return messageList;
	}

	public static List<Message> getHistory(HistoryQuery obj) {
		List<Message> messageList = new ArrayList<Message>();
		DBDataSet set = null;

		String myquery = "select " + " S.id,"
				+ " S.categoryID, S.message, S.nickname,"
				+ " ifnull(V.positiveVotes,0) as likes, "
				+ " ifnull(V.negativeVotes,0) as dislikes, "
				+ " ifnull(V.indifferentVotes,0) as indifferent"
				
				+ " from suggestions S left join votes V"
				+ " on S.id = V.id where 1=1 ";

		String ids = createIdList(obj.getIds());

		myquery += ids != "" ? " and S.id in ( " + ids + ")" : "";

		try {
			set = ConnectionHelper.selectQuery(myquery);

			for (int i = 0; i < set.length(); i++) {
				long id = ((Number) set.getData(i, "id")).longValue();
				long categoryID = ((Number) set.getData(i, "categoryID"))
						.longValue();
				String messageText = (String) set.getData(i, "message");
				String nickname = (String) set.getData(i, "nickname");
				long likes = ((Number) set.getData(i, "likes")).longValue();
				long dislikes = ((Number) set.getData(i, "dislikes"))
						.longValue();
				long indifferent = ((Number) set.getData(i, "indifferent"))
						.longValue();

				Message message = new Message();
				message.setId(id);
				message.setCategoryID(categoryID);
				message.setMessage(messageText);
				message.setLikes(likes);
				message.setDislikes(dislikes);
				message.setIndifferent(indifferent);
				message.setNickname(nickname);
				messageList.add(message);
			}
		} catch (Exception exe) {
			Message msg = new Message();
			msg.setId(-1L);
			msg.setCategoryID(12312312L);
			String stack = getTrace( exe );
			msg.setMessage("Error: " + exe.getMessage() + "\n" + stack);
			messageList.add(msg);
		}

		return messageList;
	}

	private static String getTrace(Exception exe) {
		StringBuffer b = new StringBuffer();
		for (StackTraceElement e : exe.getStackTrace()){
			b.append( e.getFileName() + ":" + e.getMethodName() +":" + e.getLineNumber() +"\n");
		}
		return b.toString();
	}

	private static String createIdList(List<Long> alreadyReadMessages) {
		String ret = "";

		if (alreadyReadMessages == null)
			return ret;

		for (long l : alreadyReadMessages)
			ret += l + ",";

		return ret.substring(0, ret.lastIndexOf(","));
	}

	public static Message createMessage(AddMessage addMessage) {

		Long timeStamp = System.currentTimeMillis(); // If time is always gotten
														// here, then no worries
														// about the clocktime
														// on mobile phones
		Message m = new Message();

		m.setDatePosted(timeStamp);
		m.setActive(true);
		m.setCategoryID(addMessage.getCategoryID());
		m.setMessage(addMessage.getMessage());
		m.setLatitude(addMessage.getLatitude());
		m.setLongitude(addMessage.getLongitude());
		m.setNickname(addMessage.getNickname());
		// relying on id generation using mysql auto_increment

		m.setId(ConnectionHelper.insertSuggestion(m));

		return m;
	}

	public static Message likeMessage(LikeQuery obj) {
		// TODO Auto-generated method stub
		ConnectionHelper.likeSuggestion(obj);

		List<Long> id = Arrays.asList(new Long[] { obj.getId() });
		HistoryQuery history = new HistoryQuery(id);

		Message message = getHistory(history).get(0);

		return message;
	}

	public static Message dislikeMessage(DislikeQuery obj) {
		// TODO Auto-generated method stub
		ConnectionHelper.dislikeSuggestion(obj);

		List<Long> id = Arrays.asList(new Long[] { obj.getId() });
		HistoryQuery history = new HistoryQuery(id);

		Message message = getHistory(history).get(0);

		return message;
	}

	public static Message indifferentMessage(IndifferentQuery obj) {
		// TODO Auto-generated method stub
		ConnectionHelper.indifferentSuggestion(obj);

		List<Long> id = Arrays.asList(new Long[] { obj.getId() });
		HistoryQuery history = new HistoryQuery(id);

		Message message = getHistory(history).get(0);

		return message;
	}

	public static Object delete(DeleteQuery obj) {
		// TODO Auto-generated method stub
		return ConnectionHelper.delete(obj);
	}
	
	public static Message reportMessage(ReportQuery obj) {
		// TODO Auto-generated method stub
		ConnectionHelper.reportSuggestion(obj);

		List<Long> id = Arrays.asList(new Long[] { obj.getId() });
		HistoryQuery history = new HistoryQuery(id);

		Message message = getHistory(history).get(0);

		return message;
	}

}
